package com.ruizhong.centercontroll.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruizhong.centercontroll.dao.TSwitchMapper;

import com.ruizhong.centercontroll.entity.TCommand;
import com.ruizhong.centercontroll.entity.TSwitch;
import com.ruizhong.centercontroll.service.TCommandService;
import com.ruizhong.centercontroll.service.TSwitchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TSwitchServiceImpl extends ServiceImpl<TSwitchMapper, TSwitch> implements TSwitchService {

    @Autowired
    private TCommandService tCommandService;

    /**
     * @param
     * @param isNew
     * @return
     * @Description:
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:36
     */
    @Override
    @Transactional
    public void saveNewSwitchList(List<Map<String, Object>> switchList, Integer pageId, boolean isNew) {
        deleteSwitchesByPageId(pageId);
        final HashMap<Integer, List<Map<String, Object>>> switchIdMapCommandList = new HashMap<>();
        final HashMap<Integer, List<Map<String, Object>>> switchIdMapInitCommandList = new HashMap<>();
        switchList.forEach(switchOB -> {
            Object value = switchOB.get("value");
            Object switchVariable = switchOB.get("switchVariable");
            Object switchVariableValue = switchOB.get("switchVariableValue");
            TSwitch tSwitch = new TSwitch();
            tSwitch.setPageId(pageId);
            tSwitch.setValue(value == null ? null : value.toString());
            tSwitch.setW(Double.parseDouble(switchOB.get("w").toString()));
            tSwitch.setH(Double.parseDouble(switchOB.get("h").toString()));
            tSwitch.setX(switchOB.get("x")==null?0:Double.parseDouble(switchOB.get("x").toString()));
            tSwitch.setY(switchOB.get("y")==null?0:Double.parseDouble(switchOB.get("y").toString()));
            tSwitch.setZ(Integer.parseInt(switchOB.get("z").toString()));
            Object displayVariableName = switchOB.get("displayVariableName");
            Object displayVariableValue = switchOB.get("displayVariableValue");
            tSwitch.setDisplayVariableName(displayVariableName == null ? null : displayVariableName.toString());
            tSwitch.setDisplayVariableValue(displayVariableValue == null ? null : displayVariableValue.toString());
            Object conditionShow = switchOB.get("conditionShow");
            tSwitch.setSwitchVariable(switchVariable == null ? null : switchVariable.toString());
            tSwitch.setSwitchVariableValue(switchVariableValue == null ? null : switchVariableValue.toString());
            tSwitch.setConditionShowData(conditionShow == null ? null : (Boolean) conditionShow ? 1 : 0);
            Object activeColor = switchOB.get("activeColor");
            Object unActiveColor = switchOB.get("unActiveColor");
            tSwitch.setActiveColor(activeColor == null ? null : activeColor.toString());
            tSwitch.setUnActiveColor(unActiveColor == null ? null : unActiveColor.toString());
            List<Map<String, Object>> switchCommandList = null;
            List<Map<String, Object>> initCommandList = null;
            Map logicGraph = (Map) switchOB.get("logicGraph");
            if (!isNew) {
                switchCommandList = (List<Map<String, Object>>) switchOB.get("switchCommandList");
                initCommandList = (List<Map<String, Object>>) switchOB.get("initCommandList");
            } else {
                ObjectMapper mapper = new ObjectMapper();
                try {
                    String logicGraphString = mapper.writeValueAsString(logicGraph);
                    tSwitch.setLogicGraphData(logicGraphString);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                Map<String, List> typeMapCommandList = TCommandServiceImpl.getCommandsByGraph(logicGraph);
                switchCommandList = typeMapCommandList.get("switchCommandList");
                initCommandList = typeMapCommandList.get("initCommandList");
            }
            save(tSwitch);
            switchIdMapCommandList.put(tSwitch.getId(), switchCommandList);
            switchIdMapInitCommandList.put(tSwitch.getId(), initCommandList);


        });
        Runnable runnable = new Runnable() {
            public void run() {
                tCommandService.saveCommandList("SWITCH", "switch", switchIdMapCommandList);
                tCommandService.saveCommandList("SWITCH", "init", switchIdMapInitCommandList);
            }
        };
        new Thread(runnable).start();
    }

    private void deleteSwitchesByPageId(Integer pageId) {
        QueryWrapper<TSwitch> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda().eq(TSwitch::getPageId, pageId);
        remove(deleteWrapper);
    }

    @Override
    public List<TSwitch> getSwitchsByPageId(Integer pageId, Double pageWidth, Double pageHeight, Double aimPageWidth, Double aimPageHeight, Boolean display) throws JsonProcessingException {
        List<TSwitch> tSwitches = lambdaQuery()
                .eq(TSwitch::getPageId, pageId)
                .list();
        for (TSwitch tSwitch : tSwitches) {
            if (!display) {
                String logicGraphData = tSwitch.getLogicGraphData();
                if (!StringUtils.isEmpty(logicGraphData)) {
                    ObjectMapper mapper = new ObjectMapper();
                    Map map = mapper.readValue(logicGraphData, Map.class);
                    tSwitch.setLogicGraph(map);
                }
                List<TCommand> slideCommands = tCommandService.getCommandListByMain(tSwitch.getId(), tSwitch.getType(), "switch");
                List<TCommand> initCommands = tCommandService.getCommandListByMain(tSwitch.getId(), tSwitch.getType(), "init");
                slideCommands = tCommandService.fillTCommands(slideCommands);
                initCommands = tCommandService.fillTCommands(initCommands);
                tSwitch.setSwitchCommandList(slideCommands);
                tSwitch.setInitCommandList(initCommands);
            }

            if (aimPageHeight != -1 && aimPageWidth != -1) {
                tSwitch.setH(Math.floor((tSwitch.getH() * aimPageHeight) / pageHeight));
                tSwitch.setW(tSwitch.getH() * 2);
                tSwitch.setX(Math.floor((tSwitch.getX() * aimPageWidth) / pageWidth));
                tSwitch.setY(Math.floor((tSwitch.getY() * aimPageHeight) / pageHeight));
            }
            tSwitch.setConditionShow(tSwitch.getConditionShowData() == null ? false : tSwitch.getConditionShowData() == 1);

        }
        return tSwitches;
    }

    @Override
    public void deleteSwitchByPageId(Integer pageId) {
        List<TSwitch> list = lambdaQuery()
                .select(TSwitch::getId)
                .eq(TSwitch::getPageId, pageId)
                .list();
        Set<Integer> switchIds = list.stream().map(TSwitch::getId).collect(Collectors.toSet());

        QueryWrapper<TSwitch> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda().eq(TSwitch::getPageId, pageId);
        remove(deleteWrapper);
        tCommandService.delCommandsByMain(switchIds, "SWITCH");
    }

    @Override
    public List<TSwitch> getSwitchIdsByPageId(Integer pageId) {
        List<TSwitch> list = lambdaQuery()
                .select(TSwitch::getId)
                .eq(TSwitch::getPageId, pageId)
                .list();
        return list;
    }

    @Override
    public void executeCommand(Map<String, Object> conditionMap, String ip) throws EncodeException, IOException {
        Map<String, Object> variableMap = (Map<String, Object>) conditionMap.get("variableSet");
        String wsToken = conditionMap.get("wsToken").toString();
        TSwitch tSwitch = getById(Integer.parseInt(conditionMap.get("id").toString()));
        List<TCommand> commandList = tCommandService.getCommandListByMain(tSwitch.getId(), tSwitch.getType(), "switch");
        tCommandService.executeCommandsAndGetReply(commandList, variableMap, wsToken, ip);
    }
}
